﻿// Copyright (c) Inossem. All rights reserved.
// Licensed under the LGPL-3.0 license. See LICENSE file in the project root for full license information.
using DWF.Studio.Custom;
using DWF.Studio.ISerivces;
using DWF.Studio.Models;
using DWF.Studio.Project;
using MahApps.Metro.Controls;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
using System.Windows.Media;
using System.Activities.XamlIntegration;
using System.Activities;
using System.Xaml;
using Microsoft.VisualBasic.Activities;
using System.Activities.Validation;
using System.Activities.Debugger.Symbol;
using DWF.Studio.Share.Log;
using System.Management.Instrumentation;
using System.Activities.Statements;
using System.Xml;
using System.Activities.Debugger;
using DWF.Studio.Host;
using System.ComponentModel;
using DWF.Studio.Script.Implementation;
using DWF.Studio.Script;
using System.Xml.Linq;

namespace DWF.Studio.Services
{
    internal class SearchService : ISearchService
    {
        private ProjectManager _projectManager = null;

        private RemoteSearchHost _searchHost = null;

        System.Timers.Timer _timerDbc;
        System.Timers.Timer _timerTrt;
        public SearchService()
        {
            _projectManager = ProjectManager.Instance;
        }
        public void OpenSearchBox(double windowWidth)
        {
            List<string> listFile = new List<string>();
            var projectInfo = _projectManager.GetProjectFolder(StaticResource.ProjectSelfFile);
            if (projectInfo.Children.Count > 0)
            {
                foreach (var item in projectInfo.Children)
                {
                    var projectFile = item as ProjectFile;
                    if (projectFile.Extension != StaticResource.XamlExtension)
                        continue;
                    listFile.Add(projectFile.FullName);
                }
            }
            _searchHost?.OpenSearchExplorer(listFile,windowWidth);
        }
        public void FocusActivityByIdRef(ScriptBase scriptbase,string idRef)
        {
            if (scriptbase is WorkflowScript)
            {
                ((WorkflowScript)scriptbase).FocusActivityByIdRef(idRef);
            }
        }
        public FrameworkElement LoadSearchHost()
        {
            var loaderHost = RemoteLoaderHost.GetCurrentInstance();
            _searchHost = new RemoteSearchHost(loaderHost.LoadSearchProxy());
            
            return _searchHost?.GetSearchExplorer();
        }
        public void Dispose()
        {
            _searchHost?.Dispose();
        }
        #region 防抖  节流阀

        /// <summary>
        /// 防抖  延迟timesMs后执行。 在此期间如果再次调用，则重新计时
        /// </summary>
        /// <param name="invoker">同步对象，一般为Control控件。 如不需同步可传null</param>
        public void Debounce(int timeMs, ISynchronizeInvoke invoker, Action action)
        {
            lock (this)
            {
                if (_timerDbc == null)
                {
                    _timerDbc = new System.Timers.Timer(timeMs);
                    _timerDbc.AutoReset = false;
                    _timerDbc.Elapsed += (o, e) =>
                    {
                        _timerDbc.Stop();
                        _timerDbc.Close();
                        _timerDbc = null;
                        invokeAction(action, invoker);
                    };
                }
                _timerDbc.Stop();
                _timerDbc.Start();
            }
        }
        /// <summary>
        /// 节流阀  即刻执行，执行之后，在timeMs内再次调用无效
        /// </summary>
        /// <param name="timeMs">不应期，这段时间内调用无效</param>
        /// <param name="invoker">同步对象，一般为控件。 如不需同步可传null</param>
        public void Throttle(int timeMs, ISynchronizeInvoke invoker, Action action)
        {
            System.Threading.Monitor.Enter(this);
            bool needExit = true;
            try
            {
                if (_timerTrt == null)
                {
                    _timerTrt = new System.Timers.Timer(timeMs);
                    _timerTrt.AutoReset = false;
                    _timerTrt.Elapsed += (o, e) =>
                    {
                        _timerTrt.Stop();
                        _timerTrt.Close();
                        _timerTrt = null;
                    };
                    _timerTrt.Start();
                    System.Threading.Monitor.Exit(this);
                    needExit = false;
                    invokeAction(action, invoker);//这个过程不能锁
                }
            }
            finally
            {
                if (needExit)
                    System.Threading.Monitor.Exit(this);
            }
        }
        private static void invokeAction(Action action, ISynchronizeInvoke invoker)
        {
            if (invoker == null)
            {
                action();
            }
            else
            {
                if (invoker.InvokeRequired)
                {
                    invoker.Invoke(action, null);
                }
                else
                {
                    action();
                }
            }
        }
        #endregion

    }
}
 